// 并发

// export default async function concurrency(promises, max) {
//   const results = new Array(promises.length);
//   const _promises = new Set();
//   for (let n = 0; n < promises.length; n++) {
//     const promise = promises[n];
//     const _promise = promise().then(data => {
//       results[n] = data;
//       console.log('data: ', data);
//       _promises.delete(promise);
//     });
//     _promises.add(_promise);
//     if (_promises.size >= max) {
//       await Promise.race(_promises);
//     }
//     await Promise.all(_promises);
//   }
//   return results;
// }

const promises = Array(20)
  .fill()
  .map(() => {
    const random = Math.ceil(Math.random() * 50) * 100;
    return () =>
      new Promise(resolve => {
        setTimeout(() => {
          resolve(random);
        }, random);
      });
  });

export default function concurrency(promises, max, callback) {
  let isEnd = false;
  const results = [];
  function _concurrency() {
    if (promises.length === 0) {
      if (!isEnd) {
        isEnd = true;
        callback(results);
      }
      return;
    }
    const promise = promises.shift();
    promise()
      .then(rets => {
        results.push(rets);
      })
      .finally(() => {
        _concurrency();
      });
  }
  Array(max).fill().forEach(_concurrency);
}

concurrency(promises, 2, results => {
  console.log('results: ', results);
});
